package com.fcscs.cservice.service.impl;

import java.math.BigDecimal;
import java.util.Date;
import java.util.List;

import org.apache.log4j.Logger;
import org.springframework.beans.factory.annotation.Autowired;

import com.fcscs.core.common.ErrorEnums;
import com.fcscs.core.service.FcsManager;
import com.fcscs.cservice.dao.CServiceCommonDao;
import com.fcscs.cservice.dao.InRoomCategoryDao;
import com.fcscs.cservice.dao.InRoomDao;
import com.fcscs.cservice.dao.InRoomItemDao;
import com.fcscs.cservice.dao.InRoomItemPriceDao;
import com.fcscs.cservice.domain.ChargeCategory;
import com.fcscs.cservice.domain.InRoomCategory;
import com.fcscs.cservice.domain.InRoomItem;
import com.fcscs.cservice.domain.InRoomItemPrice;
import com.fcscs.cservice.domain.InRoomOrder;
import com.fcscs.cservice.domain.InRoomOrderItem;
import com.fcscs.cservice.domain.InRoomOrderItemCharge;
import com.fcscs.cservice.domain.PaymentMethod;
import com.fcscs.cservice.domain.model.InRoomOrderView;
import com.fcscs.cservice.domain.model.OrderItemChargeView;
import com.fcscs.cservice.domain.model.OrderItemView;
import com.fcscs.cservice.domain.model.OrderView;
import com.fcscs.cservice.domain.validator.InRoomValidators;
import com.fcscs.cservice.service.InRoomManager;

public class InRoomManagerImpl extends FcsManager implements InRoomManager {
	
	static Logger LOGGER = Logger.getLogger(InRoomManagerImpl.class);

	@Autowired
	InRoomDao irDao;
	
	@Autowired
	CServiceCommonDao ccDao;
	
	@Autowired
	InRoomItemDao iriDao;

	@Autowired
	InRoomCategoryDao ircDao;

	@Autowired
	InRoomItemPriceDao iripDao;

	@Override
	public OrderView createOrder(long orgId, long propId, OrderView order) {
		
		InRoomOrder o = new InRoomOrder();
		o.setOrgId(orgId);
		o.setPropertyId(propId);
		o.setAmount(new BigDecimal(order.getAmount()));
		
		PaymentMethod pay = ccDao.getPayMethod(order.getBillOptionId());
		o.setBillOption(pay.getMethod());
		o.setBillOptionId(pay.getId());
		
		o.setDeliverLocation(order.getDelivLocation());
		o.setDeliveryTime(order.getDeliveryTime());
		o.setGuestProfileId(order.getGuestProfileId());
		o.setReservationId(order.getReservationId());
		o.setStatus(order.getStatus());
		
		ErrorEnums err = new InRoomValidators.InRoomOrderValidator().validate(o, true);
		if (err != null) {
			throw new RuntimeException(err.toString());
		}
		
		transferBaseVals(o, o, true);
		irDao.saveInRoomOrder(o);
		order.setOrderId(o.getId());
		
		List<OrderItemView> items = order.getOrderItemList();
		for (OrderItemView oiv : items) {
			saveOrderItem(orgId, propId, o, oiv);
		}
		
		return order;
	}

	private void saveOrderItem(long orgId, long propId, InRoomOrder o, OrderItemView oiv) {
		
		InRoomOrderItem oi = new InRoomOrderItem();
		InRoomItem im = iriDao.get(oiv.getItemId());
		
		oi.setOderId(o.getId());
		oi.setOrgId(orgId);
		oi.setPropertyId(propId);
		oi.setAmout(new BigDecimal(oiv.getAmount()));
		oi.setCategoryId(oiv.getCategoryId());
		oi.setSubcategoryId(oiv.getSubcategoryId());
		oi.setSpecialNote(oiv.getSpecialNote());
		oi.setCount(oiv.getQuantity());
		
		ChargeCategory cc = irDao.getChargeCategory(im.getChargeCategoryId());
		oi.setChargeCategoryId(cc.getId());
		oi.setChargeCategoryCode(cc.getCode());
		oi.setChargeCategoryName(cc.getName());
		oi.setChargeCategoryNameSecLang(cc.getNameSecLang());
		oi.setChargeCategoryNameThdLang(cc.getNameThdLang());
		
		InRoomCategory irc = ircDao.get(oiv.getSubcategoryId());
		oi.setPriceCategoryEnum(irc.getPriceCategoryEnum());
		
		InRoomItemPrice price = iripDao.getInRoomItemPrice(im.getId(), irc.getPriceCategoryEnum());			
		oi.setPrice(price.getPrice());
		
		ErrorEnums err1 = new InRoomValidators.InRoomOrderItemValidator().validate(oi, true);
		if (err1 != null) {
			throw new RuntimeException(err1.toString());
		}
		
		transferBaseVals(oi, oi, true);
		irDao.saveInRoomOrderItem(oi);
		
		oiv.setOrderId(o.getId());
		oiv.setOrderItemId(oi.getId());
		
		irDao.deleteCookOptions(im.getId());
		for (Long cookId : oiv.getCookOptionItemIdList()) {
			irDao.saveCookOption(im.getId(), cookId);
		}
		
		
		for (OrderItemChargeView oic :oiv.getOrderItemChargeViewList() ){
			
			InRoomOrderItemCharge iroc = new InRoomOrderItemCharge();
			iroc.setOrgId(orgId);
			iroc.setPropertyId(propId);
			iroc.setAmount(new BigDecimal(oic.getAmount()));
			
			
			
			irDao.saveInRoomOrderItemCharge(iroc);
			
		}
		
	}

	@Override
	public int calculateOrder(long orgId, long propId, OrderView order) {
		
		
		return 0;
	}

	@Override
	public List<InRoomOrderView> findInRoomOrders(long orgId, long propId, Date startTime, Date endTime, int start,
			int numResults) {
		return irDao.findInRoomOrders(orgId, propId, startTime, endTime, start, numResults);
	}

	@Override
	public int findInRoomOrdersCnt(long orgId, long propId, Date startTime, Date endTime) {
		return irDao.findInRoomOrdersCnt(orgId, propId, startTime, endTime);
	}

	@Override
	public List<InRoomOrderView> findInRoomOrders(long orgId, long propId, Date startTime, Date endTime,
			String firstName, String lastName, String status, Long categoryId, String roomNo, int start, int numResults) {
		return irDao.findInRoomOrders(orgId, propId, startTime, endTime, firstName, lastName, status, categoryId, roomNo, start, numResults);
	}

	@Override
	public int findInRoomOrdersCnt(long orgId, long propId, Date startTime, Date endTime, String firstName,
			String lastName, String status, Long categoryId, String roomNo) {
		return irDao.findInRoomOrdersCnt(orgId, propId, startTime, endTime, firstName, lastName, status, categoryId, roomNo);
	}

	@Override
	public List<InRoomOrderView> updateInRoomOrderList(List<InRoomOrderView> orderList) {
		for (InRoomOrderView v : orderList) {
			irDao.updateInRoomOrder(v.getOrderViewId(), v.getStatus());
		}
		return orderList;
	}

	@Override
	public List<InRoomOrderView> getInRoomOrderHistory(long guestProfileId, int start, int numResults) {
		return irDao.getInRoomOrderHistory(guestProfileId, start, numResults);
	}

	@Override
	public int getInRoomOrderHistoryCnt(long guestProfileId) {
		return irDao.getInRoomOrderHistoryCnt(guestProfileId);
	}

	@Override
	public OrderView getOrderView(long id) {
		return irDao.getOrderView(id);
	}

}
